<script setup lang="ts">
import { useAiChatStore } from "@/stores/aichat";
import { useModelStore } from "@/stores/model";
import { t } from "@/i18n";
import { notifyError } from "@/util/msg.ts";
import { ElScrollbar } from "element-plus";
import { getSystemConfig } from "@/system/config";
import { Vue3Lottie } from "vue3-lottie";
const chatStore = useAiChatStore();
const modelStore = useModelStore();
const isPadding = ref(false); //是否发送中

const imageInput: any = ref(null);
let imageData = ref("");
const messageContainerRef = ref<InstanceType<typeof ElScrollbar>>();
const messageInnerRef = ref<HTMLDivElement>();
// User Input Message
const userMessage = ref("");
const promptMessage = computed(() => {
  return [
    {
      content: chatStore.chatInfo.prompt || "",
      chatType: "chat",
      chatId: chatStore.activeId,
      role: "system",
      id: Date.now(),
      createAt: Date.now(),
    },
  ];
});
const requestMessages = computed(() => {
  const contextLen = modelStore.chatConfig.chat.contextLength;
  //console.log(contextLen)
  if (chatStore.messageList.length <= contextLen) {
    return [...promptMessage.value, ...chatStore.messageList];
  } else {
    // 截取最新的10条信息
    const slicedMessages = chatStore.messageList.slice(-contextLen);
    return [...promptMessage.value, ...slicedMessages];
  }
});
const sendMessage = async () => {
  if (chatStore.activeId < 1) {
    notifyError(t("index.notFindChatModel"));
    return;
  }
  if (userMessage.value) {
    // Add the message to the list
    if (isPadding.value === true) return;
    const saveMessage = {
      content: userMessage.value,
      chatId: chatStore.activeId,
      role: "user",
      id: Date.now(),
      createdAt: Date.now(),
    };
    chatStore.messageList.push(saveMessage);
    await chatStore.addMessages(chatStore.activeId, saveMessage);

    // Clear the input
    userMessage.value = "";

    // Create a completion
    isPadding.value = true;
    await createCompletion();
  }
};

const createCompletion = async () => {
  try {
    const config = getSystemConfig()
    const messageId = Date.now();
    const saveMessage: any = {
      content: "",
      role: "assistant",
      chatType: "chat",
      chatId: chatStore.activeId,
      id: messageId,
      createdAt: messageId,
    };

    const chatConfig = modelStore.chatConfig.chat;
    let postMsg: any = {
      messages: requestMessages.value,
      model: chatStore.chatInfo.model,
      engine: chatStore.chatInfo.engine,
      stream: false,
      options: chatConfig,
    };
    if (imageData.value != "") {
      const img2txtModel = await modelStore.getModel("img2txt");
      const usermsg = chatStore.messageList[chatStore.messageList.length - 1];
      postMsg = {
        model: img2txtModel.model,
        //"prompt":userMessage.value,
        engine: img2txtModel.info.engine,
        stream: false,
        options: chatConfig,
        messages: [
          {
            role: "user",
            content: usermsg.content,
            images: [imageData.value],
          },
        ],
      };
    }
    const postData: any = {
      method: "POST",
      body: JSON.stringify(postMsg),
    };

    const completion = await fetch(config.apiUrl + '/ai/chat', postData);
    //const completion:any = await modelStore.getModel(postData)
    imageData.value = "";
    if (!completion.ok) {
      const errorData = await completion.json();
      notifyError(errorData.error.message);
      isPadding.value = false;
      return;
    }
    const res = await completion.json();
    //console.log(res)
    if (res && res.choices && res.choices.length > 0) {
      if (res.choices[0].message.content) {
        const msg = res.choices[0].message.content;
        saveMessage.content = msg;
        chatStore.messageList.push(saveMessage);
        await chatStore.addMessages(chatStore.activeId, saveMessage);
      }
    }
    isPadding.value = false;
  } catch (error: any) {
    isPadding.value = false;
    notifyError(error.message);
  }
};
const scrollToBottom = () => {
  nextTick(() => {
    if (messageContainerRef && messageContainerRef.value) {
      messageContainerRef.value!.setScrollTop(
        messageInnerRef.value!.clientHeight
      );
    }
  });
};
watch(
  () => chatStore.messageList,
  () => {
    scrollToBottom();
  },
  {
    deep: true,
  }
);
const handleKeydown = (e: any) => {
  if (e.key === "Enter" && (e.altKey || e.shiftKey)) {
    // 当同时按下 alt或者shift 和 enter 时，插入一个换行符
    e.preventDefault();
    userMessage.value += "\n";
  } else if (e.key === "Enter") {
    // 当只按下 enter 时，发送消息
    e.preventDefault();
    sendMessage();
  }
};
const selectImage = async () => {
  const img2txtModel = await modelStore.getModel("img2txt");
  if (!img2txtModel) {
    notifyError(t("aichat.notEyeModel"));
    return;
  }

  imageInput.value.click();
};
const uploadImage = async (event: any) => {
  const file = event.target.files[0];
  if (!file) {
    return;
  }
  const reader = new FileReader();
  reader.onload = (e: any) => {
    imageData.value = e.target.result.split(",")[1];
  };

  reader.readAsDataURL(file);
};

</script>
<template>
  <div class="chat-bot">
    <div class="top-menu">
      <el-icon size="15" @click.stop="chatStore.showBox(true)" class="top-menu-button">
        <Tools />
      </el-icon>
      <el-icon size="15" @click.stop="chatStore.clearChatHistory" class="top-menu-button">
        <DeleteFilled />
      </el-icon>
    </div>
    <div class="messsage-area">
      <el-scrollbar v-if="chatStore.messageList.length > 0" class="message-container" ref="messageContainerRef">
        <div ref="messageInnerRef">
          <ai-chat-message v-for="message in chatStore.messageList" :key="message.messageId" :content="message.content"
            :link="message.link" :role="message.role" :createdAt="message.createdAt" />
        </div>
      </el-scrollbar>
      <div class="no-message-container" v-else>
        <Vue3Lottie animationLink="/bot/chat.json" :height="420" :width="420" />
      </div>
    </div>
    <div class="input-area">
      <div class="input-panel">
        <el-row :gutter="24" style="border-bottom: none;">
          <el-col :span="2">
            <el-button @click="selectImage" size="large" icon="Paperclip" circle :class="{ 'selected-image': imageData != '' }"/>
            <input type="file" ref="imageInput" accept="image/*" style="display: none" @change="uploadImage" />
          </el-col>
          <el-col :span="19">
            <el-input v-model="userMessage" :placeholder="t('aichat.askme')" size="large" clearable
              @keydown="handleKeydown" autofocus class="ai-input-area"/>
          </el-col>
          <el-col :span="2">
            <el-button v-if="!isPadding" @click="sendMessage" icon="Promotion" type="info" size="large" circle />
            <el-button type="primary" size="large" v-else loading-icon="Eleme" icon="Loading" loading circle />
          </el-col>
        </el-row>
      </div>
    </div>
  </div>
</template>

<style scoped lang="scss">
@import "@/assets/chat.scss";
</style>